package com.rcache.core.persistence;

import com.distributed.netty.entity.JobType;
import com.rcache.core.Element;
import com.rcache.core.cache.Rcache;
import com.rcache.core.exception.DataPersistenceException;
import com.rcache.core.persistence.jobentity.JobElementCache;
import com.rcache.core.persistence.strategy.BasePersistenceStrategy;
import com.rcache.core.persistence.utils.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class DataTimePersistenceImpl extends BasePersistenceStrategy {

    private LinkedList<JobElementCache> jobElementCacheList=new LinkedList<>();

    private static Map<Rcache,DataTimePersistenceImpl> persistences=new HashMap<>();
    public static DataTimePersistenceImpl getInstance(Rcache rcache){
        DataTimePersistenceImpl persistence = persistences.get(rcache);
        if (persistence==null){
            persistence=new DataTimePersistenceImpl(rcache);
            persistences.put(rcache,persistence);
        }
        return persistence;
    }
    private DataTimePersistenceImpl(Rcache cache) {
        Timer timer = new Timer();
        String newPaht = cache.getDiskCachePath() + "/" + cache.getCacheName();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try {
                    executeJob(jobElementCacheList,cache);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

            }
        }, cache.getDiskCacheTime(), cache.getDiskCacheTime());
    }
    /**
     * @param jobElementCacheList
     * @param cache
     * @return
     * @desc 执行任务
     */
    private boolean executeJob(List<JobElementCache> jobElementCacheList, Rcache cache) throws IOException, ClassNotFoundException {
        String newPath = cache.getDiskCachePath() + "/" + cache.getCacheName();
        for (JobElementCache jobElement : jobElementCacheList) {
            JobType type = jobElement.getJobType();
            switch (type) {
                case PUT:
                    FileUtils.putFlie(newPath, jobElement.getElement());
                    break;

                case UPDATE:
                    FileUtils.putFlie(newPath, jobElement.getElement());
                    break;

                case DELETE:
                    FileUtils.deleteFile(newPath);
                    break;

            }
        }
        jobElementCacheList.clear();
        return true;
    }

    @Override
    public boolean put(Rcache cache, Element element) throws DataPersistenceException {
        JobElementCache jobElementCache = new JobElementCache(cache, element, JobType.PUT);
        jobElementCacheList.add(jobElementCache);


        return true;
    }

    @Override
    public boolean replace(Rcache cache, Element element) throws DataPersistenceException {
        String newPaht = cache.getDiskCachePath() + "/" + cache.getCacheName();
        File file = new File(newPaht+element.getObjectKey()+".cache");
        if(file.exists()){
            try {
                FileUtils.putFlie(newPaht,element);
            } catch (IOException e) {
                throw new DataPersistenceException(e);
            } catch (ClassNotFoundException e) {
                throw new DataPersistenceException(e);
            }
            System.out.println("替换成功！");
        }
        return false;
    }

    @Override
    public boolean remove(Rcache cache, Element element) throws DataPersistenceException {
        String newPaht = cache.getDiskCachePath() + "/" +  cache.getCacheName();
        return FileUtils.deleteFile(newPaht);
    }

    @Override
    public Element get(Rcache cache, Object ElementKey) throws DataPersistenceException {
        String newPaht = cache.getDiskCachePath() + "/" + cache.getCacheName();
        try {
            return FileUtils.getFile(newPaht,ElementKey);
        } catch (IOException e) {
            throw new DataPersistenceException(e);
        } catch (ClassNotFoundException e) {
            throw new DataPersistenceException(e);
        }
    }

    @Override
    public Integer getSize(Rcache cache) throws DataPersistenceException {
                String newPaht = cache.getDiskCachePath() + "/" + cache.getCacheName();
        return  FileUtils.numberOfFiles(newPaht);

    }



    @Override
    public boolean tryRestoreFromLocal(Rcache cache) throws DataPersistenceException {
        String newPaht = cache.getDiskCachePath() + "/" + cache.getCacheName();
        try {
            return FileUtils.tryRestore(newPaht,cache);
        } catch (IOException e) {
            throw new DataPersistenceException(e);
        } catch (ClassNotFoundException e) {
            throw new DataPersistenceException(e);
        }
    }



}
